namespace EyeOpen.DddOrm.Domain.Repositories.Implementations
{
	using System.Collections.Generic;

	using System.Linq;

	using EyeOpen.DddOrm.Domain.Factories;
	using EyeOpen.Domain.Repositories;

	using EyeOpen.Domain.Transactional;

	internal class CategoryRepository
		: Repository<Category>,
		ICategoryRepository
	{
		public CategoryRepository(ITransactionalCollection session)
			: base(session)
		{
		}

		public IEnumerable<Category> CreateIfNotPresent(params string[] categoryPathList)
		{
			var categoryCollection = new List<Category>();

			foreach (var categoryPath in categoryPathList)
			{
				var categoryList = categoryPath.Split('/');

				string parent = null;

				foreach (var categoryName in categoryList)
				{
					var category = SearchAndAddCategoryIfMissing(categoryCollection, categoryName);

					if (category == null)
					{
						category =
							parent == null ?
							CategoryFactory.Create(categoryName) :
							CategoryFactory.Create(categoryName, SearchAndAddCategoryIfMissing(categoryCollection, parent, false));

						categoryCollection.Add(category);
						Add(category);
					}

					parent = categoryName;
				}
			}

			return categoryCollection;
		}

		private Category SearchAndAddCategoryIfMissing(ICollection<Category> categoryCollection, string categoryName, bool mustAdd = true)
		{
			var category = this.SingleOrDefault(x => x.Name == categoryName);

			if ((category != null) && categoryCollection.All(x => x.Name != categoryName))
			{
				if (mustAdd)
				{
					categoryCollection.Add(category);
				}

				return category;
			}

			return
				categoryCollection.SingleOrDefault(x => x.Name == categoryName);
		}
	}
}